package com.weighing.system.service.impl.server;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weighing.common.annotation.DataSource;
import com.weighing.common.enums.DataSourceType;
import com.weighing.common.utils.StringUtils;
import com.weighing.system.domain.server.ProduceOrderDetail;
import com.weighing.system.domain.server.WeighingDetail;
import com.weighing.system.domain.server.WeighingMaster;
import com.weighing.system.mapper.server.ProduceOrderDetailMapper;
import com.weighing.system.service.server.ProduceOrderDetailService;
import com.weighing.system.service.server.ProduceOrderService;
import com.weighing.system.service.server.WeighingMasterService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工单明细 Service 实现类
 */
@Service
@Transactional
@DataSource(value = DataSourceType.SLAVE)
public class ProduceOrderDetailServiceImpl extends ServiceImpl<ProduceOrderDetailMapper, ProduceOrderDetail>
        implements ProduceOrderDetailService {

    @Resource
    private WeighingMasterService weighingMasterService;

    @Resource
    private ProduceOrderDetailService produceOrderDetailService;

    @Resource
    private ProduceOrderService produceOrderService;

    @Override
    public List<ProduceOrderDetail> listByBillNo(String billNo) {
        return baseMapper.selectByBillNo(billNo);
    }

    @Override
    public List<ProduceOrderDetail> selectBySubMaterialId(String subMaterialId) {
        return baseMapper.selectBySubMaterialId(subMaterialId);
    }

    @Override
    public ProduceOrderDetail selectBySubMaterialIdAndBillNo(String billNo, String subMaterialId) {
        return baseMapper.selectBySubMaterialIdAndBillNo(subMaterialId, billNo);
    }

    @Override
    public ProduceOrderDetail checkSubMaterial(String billNo, String subMaterialId) {
        List<ProduceOrderDetail> produceOrderDetails = this.selectBySubMaterialId(subMaterialId);
        if (produceOrderDetails.isEmpty()) {
            throw new RuntimeException("未找到对应子件编号：" + subMaterialId);
        }
        ProduceOrderDetail thisProduceOrderDetail = selectBySubMaterialIdAndBillNo(billNo, subMaterialId);
        if (thisProduceOrderDetail == null) {
            throw new RuntimeException("物料:[" + subMaterialId + "]与工单 [" + billNo + "]不匹配");
        }
        if (thisProduceOrderDetail.getIsMainMaterial() == null || thisProduceOrderDetail.getMaterialType() == null) {
            throw new RuntimeException("子件编号：" + subMaterialId + " 未配置料属性和称重属性, 请联系管理员维护数据");
        }
        if (!thisProduceOrderDetail.getIsWeighing()) {
            throw new RuntimeException("子件编号:[" + subMaterialId + "]无需称重");
        }
        WeighingMaster weighingMaster = weighingMasterService.getByBillNo005(billNo);
        if (weighingMaster != null) {
            weighingMaster = weighingMasterService.getWeighingMasterByBillNo(weighingMaster.getBillNo());
        }
        if (weighingMaster == null && thisProduceOrderDetail.getIsMainMaterial() != null && !thisProduceOrderDetail.getIsMainMaterial()) {
            throw new RuntimeException("首次称重请选择主胶物料");
        }
        if (thisProduceOrderDetail.getIsWeighing() != null && !thisProduceOrderDetail.getIsWeighing()) {
            throw new RuntimeException("子件编号:[" + subMaterialId + "]无需称重");
        }
        // 主胶辅料校验
        if (weighingMaster != null && weighingMaster.getDetails() != null && !weighingMaster.getDetails().isEmpty()) {
            List<WeighingDetail> details = weighingMaster.getDetails();
            details.sort(Comparator.comparing(WeighingDetail::getRowNo).reversed());
            // 上次称重的称重单明细数据
            // 不为主料则查询最近一次的主料称重
            List<WeighingDetail> collect = details.stream().filter(WeighingDetail::getCuIsMainMaterial).sorted(Comparator.comparing(WeighingDetail::getCreateTime).reversed()).collect(Collectors.toList());
            WeighingDetail isMainMaterial = collect.get(0);
            // 最近一次主料的料属性
            ProduceOrderDetail isMainMaterialProduceOrderDetail = produceOrderDetailService.selectBySubMaterialIdAndBillNo(billNo, isMainMaterial.getCuMaterialId());
            String mainMaterialType = isMainMaterialProduceOrderDetail.getMaterialType();
            if (!mainMaterialType.substring(0, 1).equalsIgnoreCase(thisProduceOrderDetail.getMaterialType().substring(0, 1))) {
                long count1 = weighingMaster.getDetails().stream().filter(res -> !res.getProduceOrderDetail().getIsMainMaterial()
                        && res.getProduceOrderDetail().getMaterialType().substring(0, 1).equalsIgnoreCase(mainMaterialType.substring(0, 1))).count();
                if (count1 == 0) {
                    throw new RuntimeException("请先完成主胶[" + isMainMaterialProduceOrderDetail.getSubMaterialId() + "]的辅料称重");
                }
            }
            if (!thisProduceOrderDetail.getIsMainMaterial()) {
                // 辅料的料属性
                String materialType = thisProduceOrderDetail.getMaterialType();
                if (StringUtils.isNotEmpty(mainMaterialType) && StringUtils.isNotEmpty(materialType)) {
                    // 对比料属性的首字母是不是相同  不区分大小写
                    if (!mainMaterialType.substring(0, 1).equalsIgnoreCase(materialType.substring(0, 1))) {
                        // 是否有上个主料对应的辅料的称重记录 (不为主料  且辅料的料属性包含主料对应的首字母)
                        long count = details.stream().filter(res -> !res.getCuIsMainMaterial()
                                && res.getProduceOrderDetail() != null
                                && StringUtils.isNotEmpty(res.getProduceOrderDetail().getMaterialType())
                                && res.getProduceOrderDetail().getMaterialType().substring(0, 1).equals(thisProduceOrderDetail.getMaterialType().substring(0, 1))
                                && mainMaterialType.substring(0, 1).equalsIgnoreCase(res.getProduceOrderDetail().getMaterialType().substring(0, 1))).count();
                        if (count == 0) {
                            throw new RuntimeException("请先完成辅料[ " + thisProduceOrderDetail.getSubMaterialId() + " ]的主胶称重");
                        }
                    }
                }
            }
        }
        // 获取合法重量区间
        if (weighingMaster != null) {
            Map<String, Object> map = weighingMasterService.checkWeighing(weighingMaster.getBillNo(), subMaterialId, (double) 1);
            thisProduceOrderDetail.setUpper(map.get("upper").toString());
            thisProduceOrderDetail.setLower(map.get("lower").toString());
        }
        return thisProduceOrderDetail;
    }
}
